/*
 * CharacterPattern.cpp
 *
 *  Created on: 14.10.2012
 *      Author: caffeine
 */

#include "CharacterPattern.h"
#include <xml/IFactoryRecord.h>
#include <animation/IAnimationDB.h>
#include <irrMap.h>
#include <log/Log.h>
class CharacterPatternFactory:public irr::xml::IFactoryRecord{
public:
	virtual irr::core::array<irr::core::stringc> getProcessedTags(){
		irr::core::array<irr::core::stringc> res;
		res.push_back("character:pattern");
		return res;
	};

	virtual irr::xml::TagResult tagHandlerBefor(irr::xml::IFactoryEnvironment*environment,irr::xml::IXmlNode*node){
		irr::u32 id=node->getAttU32("id",0);
		CharacterPattern*cp=new CharacterPattern();
		if (!CharacterPattern::addPattern(cp,id)){
			cp->drop();
			node->setTag(0);
			return irr::xml::STOP;
		}

		node->setTag(cp);
		return irr::xml::NEXT;
	}

	virtual irr::xml::TagResult tagHandlerAfter(irr::xml::IFactoryEnvironment*environment,irr::xml::IXmlNode*node){
		CharacterPattern*cp=(CharacterPattern*)node->getTag();
		MARKER;
		cp->setAnimation(node->getAttString("animation"));
		MARKER;
		return irr::xml::NEXT;
	}
};

class CharacterPatternItemFactory:public irr::xml::IFactoryRecord{
public:
	virtual irr::core::array<irr::core::stringc> getProcessedTags(){
		irr::core::array<irr::core::stringc> res;
		res.push_back("character:pattern:group");
		return res;
	};

	virtual irr::xml::TagResult tagHandlerBefor(irr::xml::IFactoryEnvironment*environment,irr::xml::IXmlNode*node){
		if (!node->getParent() || !node->getParent()->getTag()){
			return irr::xml::STOP;
		}
		irr::core::stringc href=node->getAttString("href","");
		if (href=="")
			return irr::xml::STOP;

		CharacterPattern*cp=(CharacterPattern*)node->getParent()->getTag();
		irr::core::stringc type=node->getAttString("type","");
		CharacterPatternGroup*group=0;
		if (type=="facial")
			group=cp->getFacial();

		if (type=="hair")
			group=cp->getHair();

		if (type=="head")
			group=cp->getHair_head();

		if (type=="skin")
			group=cp->getskins();

		if (type=="face")
			group=cp->getFace();

		if (type=="feet")
			group=cp->getFeet();

		if (type=="body")
			group=cp->getBodys();

		if (type=="hands")
			group=cp->getHands();

		if (type=="lags")
			group=cp->getLags();

		if (type=="add")
			group=cp->getAdds();

		if (!group)
			return irr::xml::STOP;

		group->addRecord(environment->getDevice()->getFileSystem()->getAbsolutePath(href));

		return irr::xml::NEXT;
	}
};


CharacterPattern::CharacterPattern() {
	/*
	facial=new CharacterPatternGroup();
	hair=new CharacterPatternGroup();
	hair_head=new CharacterPatternGroup();
	skins=new CharacterPatternGroup();
	face=new CharacterPatternGroup();
	bodys=new CharacterPatternGroup();
	feet=new CharacterPatternGroup();
	hands=new CharacterPatternGroup();
	lags=new CharacterPatternGroup();
	adds=new CharacterPatternGroup();
*/
	groups=new CharacterPatternGroup*[BodyElementType_COUNT-1];
	for (int i=0;i<BodyElementType_COUNT;i++)
		groups[i]=new CharacterPatternGroup();

	animation=0;
}

CharacterPattern::~CharacterPattern() {

	for (int i=0;i<BodyElementType_COUNT;i++)
		groups[i]->drop();
	delete[]groups;
/*
	adds->drop();
	lags->drop();
	facial->drop();
	hair->drop();
	hair_head->drop();
	skins->drop();
	face->drop();
	bodys->drop();
	feet->drop();
	hands->drop();
	*/
	if (animation)
		animation->drop();
}

CharacterPatternGroup*CharacterPattern::getGroups(BodyElementType type){
	return groups[type];
}

CharacterPatternGroup*CharacterPattern::getLags(){
	return getGroups(LAGS);
}

CharacterPatternGroup*CharacterPattern::getAdds(){
	return getGroups(ADD);
}

void CharacterPattern::setAnimation(irr::core::stringc name){
	MARKER;
	if (animation)
		animation->drop();
	MARKER;
	animation=irr::animation::getDefaultAnimationDB()->getByName(name);
	MARKER;
	if (animation)
		animation->grab();
	MARKER;
}

irr::animation::IAnimation*CharacterPattern::getAnimation(){
	return animation;
}
CharacterPatternGroup*CharacterPattern::getFacial(){
	return getGroups(FACIAL);
}
CharacterPatternGroup*CharacterPattern::getHair(){
	return getGroups(HAIR);
}
CharacterPatternGroup*CharacterPattern::getHair_head(){
	return getGroups(HAIR_HEAD);
}
CharacterPatternGroup*CharacterPattern::getskins(){
	return getGroups(SKIN);
}
CharacterPatternGroup*CharacterPattern::getFace(){
	return getGroups(FACE);
}
CharacterPatternGroup*CharacterPattern::getBodys(){
	return getGroups(BODY);
}

CharacterPatternGroup*CharacterPattern::getFeet(){
	return getGroups(FEET);
}

CharacterPatternGroup*CharacterPattern::getHands(){
	return getGroups(HANDS);
}

//----------STATIC METHOD----------//

irr::core::map<irr::u32,CharacterPattern*> patterns;

void CharacterPattern::regFactory(irr::xml::IFactoryEnvironment*environment){
	irr::xml::IFactoryRecord*temp=new CharacterPatternFactory();
	environment->registerHandler(temp);
	temp->drop();

	temp=new CharacterPatternItemFactory();
	environment->registerHandler(temp);
	temp->drop();
}

bool CharacterPattern::addPattern(CharacterPattern*pattern,irr::u32 ID){
	if (getPatternByID(ID))
		return false;
	patterns.insert(ID,pattern);
	return true;
}

CharacterPattern*CharacterPattern::getPatternByID(irr::u32 ID){
	irr::core::map<irr::u32,CharacterPattern*>::Node*it=patterns.find(ID);
	if (!it)
		return 0;
	return it->getValue();
}

//
